home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- * flextr.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
- *
- * Copyright (C) 1989,1990 by Michael Mauldin. Permission is granted
- * to use this file in whole or in part for any purpose, educational,
- * recreational or commercial, provided that this copyright notice
- * is retained unchanged. This software is available to all free of
- * charge by anonymous FTP and in the UUNET archives.
- *
- * flextr.c: Extract a rectangle and/or resize it.
- *
- * CONTENTS
- * extract_fbm (input, output, xo, yo, w, h, ow, oh, title, credits)
- *
- * EDITLOG
- * LastEditDate = Mon Jun 25 17:03:19 1990 - Michael Mauldin
- * LastFileName = /usr2/mlm/src/misc/fbm0.99/flextr.c
- *
- * HISTORY
- * 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
- * Package for Release 1.0
- *
- * 13-Jun-90 Michael Mauldin (mlm) at Carnegie Mellon University
- * Final release (version 1.0) mlm@cs.cmu.edu
- *
- * 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
- * Beta release (version 0.9) mlm@cs.cmu.edu
- *
- * 12-Nov-88 Michael Mauldin (mlm) at Carnegie-Mellon University
- * Created.
- *****************************************************************/
-
- # include <stdio.h>
- # include <math.h>
- # include <ctype.h>
- # include "fbm.h"
-
- /****************************************************************
- * extract_fbm: Resize a bitmap
- * copy input [xo:xo+w yo:yo+h] to output [ow oh]
- ****************************************************************/
-
- #ifndef lint
- static char *fbmid =
- "$FBM flextr.c <1.0> 25-Jun-90 (C) 1989,1990 by Michael Mauldin, source \
- code available free from MLM@CS.CMU.EDU and from UUNET archives$";
- #endif
-
- extract_fbm (input, output, xo, yo, w, h, ow, oh, title, credits)
- FBM *input, *output;
- int xo, yo, h, w, oh, ow;
- char *title, *credits;
- { int k, rowlen;
-
- if ((w != ow || h != oh) && input->hdr.bits != 8)
- { fprintf (stderr,
- "Can't resize images with %d bits per pixel\n", input->hdr.bits);
- return (0);
- }
-
- if (input->hdr.physbits != 8)
- { fprintf (stderr,
- "Can't extract images with %d physbits per pixel\n",
- input->hdr.physbits);
- return (0);
- }
-
- if (h < 1 || w < 1 || oh < 1 || ow < 1)
- { fprintf (stderr, "Extract: zero dimension [%dx%d] => [%dx%d]\n",
- w, h, ow, oh);
- return (0);
- }
-
- fprintf (stderr,
- "Extract \"%s\" <%d,%d> [%dx%d] => [%dx%d] %d pixels\n",
- title ? title : input->hdr.title[0] ? input->hdr.title : "untitled",
- xo, yo, w, h, ow, oh, ow*oh);
-
- if (xo+w > input->hdr.cols)
- { fprintf (stderr, "Warning, input exceeds image horizontally\n");
- fprintf (stderr, " xo %d, w %d, input->hdr.cols %d\n",
- xo, w, input->hdr.cols);
- }
- if (yo+h > input->hdr.rows)
- { fprintf (stderr, "Warning, input exceeds image vertically\n");
- fprintf (stderr, " yo %d, h %d, input->hdr.rows %d\n",
- yo, h, input->hdr.rows);
- }
-
- /* Calculate length of row (pad to even byte boundary) */
- rowlen = 2 * ((ow * input->hdr.physbits + 15) / 16);
-
- /* Now build header for output bit map */
- output->hdr.cols = ow;
- output->hdr.rows = oh;
- output->hdr.planes = input->hdr.planes;
- output->hdr.bits = input->hdr.bits;
- output->hdr.physbits = input->hdr.physbits;
- output->hdr.rowlen = rowlen;
- output->hdr.plnlen = oh * output->hdr.rowlen;
- output->hdr.clrlen = input->hdr.clrlen;
- output->hdr.aspect = input->hdr.aspect * ow * h / (oh * w);
-
- if (title == NULL || *title == '\0')
- { strncpy (output->hdr.title, input->hdr.title, FBM_MAX_TITLE); }
- else
- { strcpy (output->hdr.title, title); }
-
- if (credits == NULL || *credits == '\0')
- { strncpy (output->hdr.credits, input->hdr.credits, FBM_MAX_TITLE); }
- else
- { strcpy (output->hdr.credits, credits); }
-
- /* Allocate space for output bits */
- alloc_fbm (output);
-
- copy_clr (input, output);
-
- /* Warning about resizing mapped image */
- if (input->hdr.clrlen > 0 && (w != ow || h != oh))
- { fprintf (stderr,
- "Warning, %s\n %s\n",
- "resizing a mapped image is probably not what you want",
- "I'll do it anyway, but you should probably use unmap first.");
- }
-
- /* Now extract each plane separately */
- for (k=0; k<output->hdr.planes; k++)
- { if (! extract_one (&(input->bm[k * input->hdr.plnlen]),
- &(output->bm[k * output->hdr.plnlen]),
- input->hdr.cols, input->hdr.rows,
- input->hdr.rowlen, output->hdr.rowlen,
- xo, yo, w, h, ow, oh))
- { free_fbm (output); return (0); }
- }
-
- return (1);
- }
-
- /****************************************************************
- * extract_one: Resize a bitmap
- * copy input [xo:xo+w yo:yo+h] to output [ow oh]
- ****************************************************************/
-
- extract_one (inbm, outbm, cols, rows, inlen, outlen, xo, yo, w, h, ow, oh)
- unsigned char *inbm, *outbm;
- int inlen, outlen, xo, yo, h, w, oh, ow;
- { register int xf, yf, xi, i;
- register unsigned char *bm1, *bm2, *obm;
- int j, yi, dc;
-
- /* Check for scale of 1-1, special case for speed */
- if (w == ow && h == oh && xo >= 0 && yo >= 0 && xo+w <= cols && yo+h <= rows)
- { for (j=0; j<h; j++)
- { bm1 = &inbm[(j+yo) * inlen];
- obm = &outbm[j * outlen];
-
- for (i=0; i<w; i++)
- { obm[i] = bm1[i + xo]; }
- }
- }
- else
- {
- for (j = 0; j<oh; j++)
- { yi = (j*h / oh) + yo;
- yf = (j*h % oh);
-
- obm = &outbm[j * outlen];
- bm1 = &inbm[yi * inlen];
- bm2 = bm1 + inlen;
-
- for (i=0; i<ow; i++)
- { xi = (i*w / ow) + xo;
- xf = (i*w % ow);
-
- if (xi < 0 || yi < 0 ||
- xi > cols-2 ||
- yi > rows-2)
- { static cntr = 0;
-
- /* If right on edge, just use edge value */
- if ((xi == cols-1 &&
- yi >= 0 && yi <= rows-1) ||
- (yi == rows-1 &&
- xi >= 0 && xi <= cols-1))
- { obm[i] = bm1[xi]; }
- else
- { obm[i] = 255;
-
- if (cntr++ < 3)
- { fprintf (stderr,
- "i,j %d,%d => xi,yi %d,%d, out of bounds %d,%d\n",
- i, j, xi, yi, cols, rows);
- fprintf (stderr,
- "w %d, h %d, ow %d, oh %d\n\n",
- w, h, ow, oh);
- }
- }
- }
- else
- { dc = ( bm1[xi] * (ow-xf)*(oh-yf) +
- bm2[xi] * (ow-xf)*(yf) +
- bm1[xi+1] * (xf)*(oh-yf) +
- bm2[xi+1] * (xf)*(yf) ) / (ow*oh);
-
- if (dc < 0) { dc = 0; }
- else if (dc > 255) { dc = 255; }
-
- obm[i] = dc;
- }
- }
- }
- }
-
- return (1);
- }
-